import { Client } from 'ssh2';
import { log } from '../utils/logger.js';

/**
 * SSH连接管理服务
 */
export class SSHService {
  constructor() {
    // 存储活跃的SSH连接 { connectionId: { client, stream, serverId, userId } }
    this.connections = new Map();
  }

  /**
   * 创建SSH连接
   */
  async connect(connectionId, serverConfig, userId) {
    return new Promise((resolve, reject) => {
      const client = new Client();
      
      // 连接配置
      const config = {
        host: serverConfig.host,
        port: serverConfig.port || 22,
        username: serverConfig.username,
        readyTimeout: 30000,
        keepaliveInterval: 10000
      };

      // 根据认证类型添加凭证
      if (serverConfig.auth_type === 'key' && serverConfig.private_key) {
        config.privateKey = serverConfig.private_key;
      } else if (serverConfig.password) {
        config.password = serverConfig.password;
      } else {
        return reject(new Error('缺少认证凭证'));
      }

      // 连接事件处理
      client.on('ready', () => {
        log.ssh(`SSH连接成功: ${serverConfig.name} (${serverConfig.host})`, {
          userId,
          serverId: serverConfig.id,
          connectionId
        });

        // 存储连接
        this.connections.set(connectionId, {
          client,
          serverId: serverConfig.id,
          userId,
          serverName: serverConfig.name,
          connectedAt: new Date()
        });

        resolve(client);
      });

      client.on('error', (err) => {
        log.error(`SSH连接失败: ${serverConfig.name}`, {
          error: err.message,
          userId,
          serverId: serverConfig.id
        });
        reject(err);
      });

      client.on('close', () => {
        log.ssh(`SSH连接关闭: ${serverConfig.name}`, {
          userId,
          serverId: serverConfig.id,
          connectionId
        });
        this.connections.delete(connectionId);
      });

      // 发起连接
      try {
        client.connect(config);
      } catch (error) {
        log.error('SSH连接启动失败', { error: error.message });
        reject(error);
      }
    });
  }

  /**
   * 创建Shell会话
   */
  async createShell(connectionId) {
    const connection = this.connections.get(connectionId);
    
    if (!connection) {
      throw new Error('连接不存在');
    }

    return new Promise((resolve, reject) => {
      connection.client.shell({ term: 'xterm-256color' }, (err, stream) => {
        if (err) {
          log.error('创建Shell失败', { error: err.message, connectionId });
          reject(err);
          return;
        }

        log.ssh('Shell会话创建成功', { connectionId });
        connection.stream = stream;
        resolve(stream);
      });
    });
  }

  /**
   * 执行命令
   */
  async executeCommand(connectionId, command) {
    const connection = this.connections.get(connectionId);
    
    if (!connection) {
      throw new Error('连接不存在');
    }

    return new Promise((resolve, reject) => {
      connection.client.exec(command, (err, stream) => {
        if (err) {
          log.error('执行命令失败', { error: err.message, command, connectionId });
          reject(err);
          return;
        }

        let stdout = '';
        let stderr = '';

        stream.on('data', (data) => {
          stdout += data.toString();
        });

        stream.stderr.on('data', (data) => {
          stderr += data.toString();
        });

        stream.on('close', (code) => {
          log.ssh('命令执行完成', { command, code, connectionId });
          resolve({ stdout, stderr, code });
        });
      });
    });
  }

  /**
   * 断开连接
   */
  disconnect(connectionId) {
    const connection = this.connections.get(connectionId);
    
    if (connection) {
      connection.client.end();
      this.connections.delete(connectionId);
      log.ssh('SSH连接断开', { connectionId });
      return true;
    }
    
    return false;
  }

  /**
   * 获取连接信息
   */
  getConnection(connectionId) {
    return this.connections.get(connectionId);
  }

  /**
   * 获取用户的所有连接
   */
  getUserConnections(userId) {
    const userConnections = [];
    
    for (const [connectionId, connection] of this.connections.entries()) {
      if (connection.userId === userId) {
        userConnections.push({
          connectionId,
          serverId: connection.serverId,
          serverName: connection.serverName,
          connectedAt: connection.connectedAt
        });
      }
    }
    
    return userConnections;
  }

  /**
   * 断开用户的所有连接
   */
  disconnectAllUserConnections(userId) {
    let count = 0;
    
    for (const [connectionId, connection] of this.connections.entries()) {
      if (connection.userId === userId) {
        this.disconnect(connectionId);
        count++;
      }
    }
    
    log.ssh(`断开用户的所有SSH连接`, { userId, count });
    return count;
  }

  /**
   * 获取活跃连接数
   */
  getActiveConnectionCount() {
    return this.connections.size;
  }
}

// 创建单例
export const sshService = new SSHService();

